package com.briup.day19;

import java.util.ArrayList;
import java.util.concurrent.*;

public class ThreadPoolTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test2();
    }

    private static void test2() throws ExecutionException, InterruptedException {
        // ScheduledThreadPoolExecutor
        ScheduledThreadPoolExecutor executor =
                new ScheduledThreadPoolExecutor(10);
        Callable<String> task = () -> {
            String name = Thread.currentThread().getName();
            System.out.println("hello world!!!!! ============>" + name);
            return name;
        };
        // 在控制台中输出10个hello world
        for (int i = 0; i < 10; i++) {
            // 三秒后执行输出hello world
            ScheduledFuture<String> schedule = executor.schedule(task, 3, TimeUnit.SECONDS);
//            System.out.println(schedule.get());
        }
        executor.shutdown();
    }

    private static void test() {
         /*
            由于线程频繁的创建与销毁操作是及其耗费系统资源的，
            所以不推荐让线程频繁的创建与销毁，而是让线程能够实现复用；
            线程池：线程池就是为了解决上述问题而产生的一种技术，就像是
            现实生活中的人事部；
            线程池中可以规定统一维护多少个核心线程，以及最大的线程数；
            同时还可以维护线程的代办事项（任务），即维护一个任务队列，
            当线程中当前正在执行的任务结束后，可以继续从任务队列中
            获取新的任务继续执行；还可以设定空闲线程最大存活时间；

            Java中线程池的源头为接口 Executor，内部常用的实现类包括
            ThreadPoolExecutor、ScheduledThreadPoolExecutor
              int corePoolSize, 核心线程数
              int maximumPoolSize, 最大可维护的线程数
              long keepAliveTime, 空闲线程最大的存活时间
              TimeUnit unit, 存活时间的单位
              BlockingQueue<Runnable> workQueue 代办任务队列
         */
        // 创建一个最大线程数为10，最大可等待队列为10，并且空闲线程最大存活1000秒的线程池
        // 一次性最大能够接收的任务为 最大线程数+最大可等待队列的结果 20；
        // 在线程池接收到任务之后，会先创建核心线程，将任务优先分配给核心线程，
        // 当任务数多于核心线程时，就先将任务放入到任务等待队列中，
        // 当任务队列也满了时，才会创建剩余非核心线程
        ThreadPoolExecutor threadPool =
                new ThreadPoolExecutor(5, 10,
                        1000, TimeUnit.SECONDS,
                        new ArrayBlockingQueue<>(10));

        // 创建一个ArrayList数组，给其赋值2500个元素
        ArrayList<Integer> list = new ArrayList<>();
        Runnable task = () -> {
            System.out.println("当前执行任务的线程为："
                    + Thread.currentThread().getName());
            for (int i = 0; i < 100; i++) {
                list.add(i);
            }
        };
        // 分配20个任务
        for (int i = 0; i < 20; i++) {
            // 让线程池分配任务
            threadPool.execute(task);
        }
        System.out.println(list.size());
        // 当程序执行完毕后注意关闭线程池，
        // 该关闭按钮会等待线程池中现有任务执行完毕之后才关闭
        threadPool.shutdown();
    }
}
